home *** CD-ROM | disk | FTP | other *** search
/ IRIX Base Documentation 2002 November / SGI IRIX Base Documentation 2002 November.iso / usr / share / catman / p_man / catD / xtalk_intr.z / xtalk_intr
Encoding:
Text File  |  2002-10-03  |  10.5 KB  |  265 lines

  1.  
  2.  
  3.  
  4. xxxxttttaaaallllkkkk____iiiinnnnttttrrrr((((DDDD3333))))                                                  xxxxttttaaaallllkkkk____iiiinnnnttttrrrr((((DDDD3333))))
  5.  
  6.  
  7.  
  8. NNNNAAAAMMMMEEEE
  9.      _xxxx_tttt_aaaa_llll_kkkk______iiii_nnnn_tttt_rrrr______aaaa_llll_llll_oooo_cccc - allocate a XIO Interrupt channel
  10.      _xxxx_tttt_aaaa_llll_kkkk______iiii_nnnn_tttt_rrrr______cccc_oooo_nnnn_nnnn_eeee_cccc_tttt - connect handling function
  11.      _xxxx_tttt_aaaa_llll_kkkk______iiii_nnnn_tttt_rrrr______dddd_iiii_ssss_cccc_oooo_nnnn_nnnn_eeee_cccc_tttt - disconnect handling function
  12.      _xxxx_tttt_aaaa_llll_kkkk______iiii_nnnn_tttt_rrrr______ffff_rrrr_eeee_eeee - release a XIO Interrupt channel
  13.  
  14. SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
  15.      #include <sys/XIO/xtalk.h>
  16.  
  17.      xtalk_intr_t
  18.      xtalk_intr_alloc(vertex_hdl_t _v_h_d_l,
  19.                 device_desc_t _d_e_s_c,
  20.                 vertex_hdl_t _o_w_n_e_r)
  21.  
  22.      int
  23.      xtalk_intr_connect(xtalk_intr_t _i_n_t_r,
  24.                intr_func_t _f_u_n_c,
  25.                intr_arg_t _a_r_g,
  26.                xtalk_intr_setfunc_t _s_e_t_f_u_n_c,
  27.                void *_s_e_t_f_u_n_c__a_r_g,
  28.                void *_t_h_r_e_a_d)
  29.  
  30.      void
  31.      xtalk_intr_disconnect(xtalk_intr_t _i_n_t_r)
  32.  
  33.      void
  34.      xtalk_intr_free(xtalk_intr_t _i_n_t_r)
  35.  
  36.  
  37.    AAAArrrrgggguuuummmmeeeennnnttttssss
  38.      _v_h_d_l    is the appropriate XIO connection point.
  39.  
  40.      _d_e_s_c    is a device descriptor, usually zero.
  41.  
  42.      _l_i_n_e_s   specifies one or more of the XIO Interrupt pins connected to the
  43.              card.
  44.  
  45.      _o_w_n_e_r   is an appropriate vertex handle to use when printing messages
  46.              about this particular interrupt, and is usually a vertex created
  47.              by the device driver.
  48.  
  49.      _i_n_t_r    is the opaque interrupt channel handle
  50.  
  51.      _f_u_n_c    is a function to be used for interrupt service
  52.  
  53.      _a_r_g     is the parameter to pass to the function when this particular
  54.              interrupt occurs, and is commonly a pointer to a driver-private
  55.              data structure.
  56.  
  57.      _s_e_t_f_u_n_c is a callback function that will be called by the infrastructure
  58.              to set up a new interrupt target widget number, address, or
  59.              vector.  It will always be called once, to set the initial
  60.  
  61.  
  62.  
  63.                                                                         PPPPaaaaggggeeee 1111
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70. xxxxttttaaaallllkkkk____iiiinnnnttttrrrr((((DDDD3333))))                                                  xxxxttttaaaallllkkkk____iiiinnnnttttrrrr((((DDDD3333))))
  71.  
  72.  
  73.  
  74.              assignment; the system may call it again, later, if the interrupt
  75.              needs to be migrated to a different target.
  76.  
  77.      _s_e_t_f_u_n_c__a_r_g
  78.              is an opaque value, owned by the driver, that is stored within
  79.              the interrupt structure and can be retrieved by the driver using
  80.              _x_t_a_l_k__i_n_t_r__s_f_a_r_g__g_e_t().
  81.  
  82.      _t_h_r_e_a_d  is reserved for use by the interrupt threads subsystem, and
  83.              should be NULL.
  84.  
  85.  
  86. DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
  87.      When a device driver wishes to accept interrupt events from a device, the
  88.      system needs to assign a target CPU and allocate a vector number on that
  89.      CPU's XIO interface. The target information is then reported back to the
  90.      driver, which can set up its device to send XIO interrupt packets with
  91.      the proper data to the correct target port and address.  Only then can a
  92.      service function be attached to the interrupt channel.
  93.  
  94.      This three-phase handling of the XIO interrupt setup allows several
  95.      things:
  96.  
  97.      +o   The service function can be changed (or disconnected entirely)
  98.          without losing any hardware resources and having to reallocate them
  99.          in the process.
  100.  
  101.      +o   The interrupt can be retargeted from one processor to another, should
  102.          upper layers of software decide this is necessary.
  103.  
  104.      Since the interrupt delivery mechanism carries the address of the
  105.      interrupt function, it is important to disconnect your interrupts before
  106.      unloading your driver. Your driver will not be auto-loaded when an
  107.      interrupt occurs.
  108.  
  109.      The necessary sequence of calls is as follows:
  110.  
  111.      +o   When the device is initially attached, _x_t_a_l_k__i_n_t_r__a_l_l_o_c() should be
  112.          used to establish interrupt connectivity between the device and the
  113.          processor.  It is common to call _x_t_a_l_k__i_n_t_r__c_o_n_n_e_c_t() at this time.
  114.  
  115.      +o   _x_t_a_l_k__i_n_t_r__c_o_n_n_e_c_t() triggers the first callback to the setfunc so
  116.          the driver can correctly configure its hardware for the target
  117.          processor, XIO port, XIO address, and vector number.
  118.  
  119.      +o   If the device driver is automatically unloading, it will be unloaded
  120.          shortly after the attaches are complete.  Since the driver text is
  121.          going away, it is important for all interrupts to be disconnected.
  122.          _x_t_a_l_k__i_t_e_r_a_t_e() should be used to call a function with each of the
  123.          driver's connection points, which can then execute the proper
  124.          disconnect calls.
  125.  
  126.  
  127.  
  128.  
  129.                                                                         PPPPaaaaggggeeee 2222
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136. xxxxttttaaaallllkkkk____iiiinnnnttttrrrr((((DDDD3333))))                                                  xxxxttttaaaallllkkkk____iiiinnnnttttrrrr((((DDDD3333))))
  137.  
  138.  
  139.  
  140.      +o   When the device driver is reloaded, its _p_f_xinit() entry point is
  141.          called.  The device driver should again use _x_t_a_l_k__i_t_e_r_a_t_e(), this
  142.          time to call a function that will re-connect interrupts to the new
  143.          address of the service function.  No special logic is needed to
  144.          prevent this at the initial load time, since _x_t_a_l_k__i_t_e_r_a_t_e() is a
  145.          no-operation when the device driver is not registered.
  146.  
  147.      +o   When the device driver is unregistered, the act of unregistering with
  148.          the XTALK infrastructure will trigger calls to _p_f_xdetach() which
  149.          should disconnect all interrupt service.
  150.  
  151.  
  152.    AAAAlllltttteeeerrrrnnnnaaaatttteeee SSSScccceeeennnnaaaarrrriiiioooo
  153.      Some devices may not require interrupt service when they are not open.
  154.      Leaving an interrupt allocated but not connected will keep it disabled,
  155.      possibly reducing impact on the system from devices that may interrupt
  156.      when there is no interest from the driver in actually performing any
  157.      services.
  158.  
  159.      If this is true, then the scenario above may be somewhat simplified:
  160.  
  161.      +o   If interrupts are required as part of setting up the device in
  162.          _p_f_xattach(), then they can be connected, then disconnected before
  163.          _p_f_xattach() returns.
  164.  
  165.      +o   Since interrupts are not active when the device is closed,
  166.          _p_f_xunload() and _p_f_xdetach() do not need to worry about disconnecting
  167.          the interrupt services, and _p_f_xinit() does not need to worry about
  168.          reconnecting them.  Instead, _p_f_xopen() would connect the interrupt on
  169.          first open, and _p_f_xclose() would disconnect the interrupt on last
  170.          close.
  171.  
  172.  
  173. EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
  174.      Here is a simple example of how an XIO device driver might get interrupt
  175.      service started.
  176.  
  177.      xiofoo_attach(vertex_hdl_t xconn_vhdl)
  178.      {
  179.           xtalk_intr_t   intr;
  180.           struct xiofoo_regs  *xiofoo_regs;
  181.  
  182.           ...
  183.           /* This driver uses both line A and line B,
  184.            * and wants to route both to the same
  185.            * service function.
  186.            */
  187.           intr = xtalk_intr_alloc(xconn_vhdl, 0, xiofoo_vhdl);
  188.  
  189.           /* Arrange for the "soft" pointer to
  190.            * be the parameter for the interrupt,
  191.            * and for the device registers themselves
  192.  
  193.  
  194.  
  195.                                                                         PPPPaaaaggggeeee 3333
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202. xxxxttttaaaallllkkkk____iiiinnnnttttrrrr((((DDDD3333))))                                                  xxxxttttaaaallllkkkk____iiiinnnnttttrrrr((((DDDD3333))))
  203.  
  204.  
  205.  
  206.           * to be the parameter for the setfunc()
  207.            * call.
  208.            */
  209.           xtalk_intr_connect(
  210.                intr,
  211.                xiofoo_intr,
  212.                (intr_arg_t)xiofoo_soft,
  213.                xiofoo_intr_setfunc,
  214.                (void *)xiofoo_regs,
  215.                (void *)0);
  216.           ...
  217.      }
  218.  
  219.      static void
  220.      xiofoo_intr_setfunc(xtalk_intr_t intr)
  221.      {
  222.           xwidgetnum_t   targ = xtalk_intr_target_get(intr);
  223.           iopaddr_t addr = xtalk_intr_addr_get(intr);
  224.           xtalk_intr_vector_t vect = xtalk_intr_vector_get(intr);
  225.           struct xiofoo_regs  *fooregs;
  226.  
  227.           fooregs = (struct xiofoo_regs *)
  228.                xtalk_intr_sfarg_get(intr);
  229.  
  230.           fooregs->control &= FOOREGS_INT_ENABLE;
  231.           fooregs->intr_port = targ;
  232.           fooregs->intr_addr = addr;
  233.           fooregs->intr_vect = vect;
  234.           fooregs->control |= FOOREGS_INT_ENABLE;
  235.      }
  236.  
  237.  
  238.      /
  239.  
  240.  
  241. SSSSEEEEEEEE AAAALLLLSSSSOOOO
  242.      xtalk(D3), xtalk_dma(D3), xtalk_error(D3), xtalk_get(D3), xtalk_pio(D3).
  243.  
  244.  
  245. DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS
  246.      _x_t_a_l_k__i_n_t_r__a_l_l_o_c() will return a null value if it can not allocate
  247.      memory.
  248.  
  249.      _x_t_a_l_k__i_n_t_r__c_o_n_n_e_c_t() will return a zero for success, or a negative value
  250.      on failure.  Since the channel is preallocated, the only interesting
  251.      failure is the attempt to use a null interrupt cookie value.
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.                                                                         PPPPaaaaggggeeee 4444
  262.  
  263.  
  264.  
  265.